package valuecomusa.fijibus.eticket.shorthaul;


import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.MediaPlayer;
//import android.nfc.NfcAdapter;
import android.os.*;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import valuecomusa.fijibus.eticket.*;
import valuecomusa.fijibus.eticket.db.shorthaul.BusinessDBHandler;
import valuecomusa.fijibus.eticket.db.shorthaul.GpsDBHandler;
import valuecomusa.fijibus.eticket.dialog.refund;
import valuecomusa.fijibus.eticket.dto.GpsCurrentLocationValue;
import valuecomusa.fijibus.eticket.dto.StagesOfRouteValue;
import valuecomusa.fijibus.eticket.ws.MemberValue;
import valuecomusa.fijibus.eticket.ws.PassengerTypeValue;
import valuecomusa.fijibus.eticket.ws.TransactionValue;
import valuecomusa.fijibus.eticket.ws.VoucherValue;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class CheckInV2Cash_4more extends SunbeamActivity
{
	private static int counter = 1;
    private String TAG = "CheckIn-V2-4more";
    private StagesOfRouteValue currentLocation;

    private int[] passengerCount = new int[5]; //adult, child, senior, disabled, student
    //private int[] stageColors = new int[]{0x7CFC00, 0x00BFFF, 0xFFFF00, 0xD2691E, 0xDDA0DD, 0x32CD32, 0xFF7F50};
    private double totalFare;
    private double xStageFare;
    private int selectedStage;
	private int stageCount;
    //--
    //private double oneStageFare;
    //--
    private TextView totalFareTextView;
	private RadioGroup passengerTypeGroup;
	//--
    private BusinessDBHandler db;
    private GpsDBHandler gpsDb;
	//--
//	private NfcAdapter nfcAdapter;
//	private PendingIntent mPendingIntent;

    private List<PassengerTypeValue> passengerTypeList;
    //--
    private ProgressDialog progress;

	public CheckInV2Cash_4more()
	{
		TAG = TAG + "." + counter++;
		if(counter > 1000000)
			counter = 1;
	}

    private double GetPassengerTypeDiscount(String type)
    {
        for (PassengerTypeValue xx : this.passengerTypeList)
        {
            if (xx.Type.toLowerCase().equals(type.toLowerCase()))
                return xx.Discount / 100;
        }
        return 0;
    }

    private void Initialize()
    {
//		nfcAdapter = NfcAdapter.getDefaultAdapter(this);
//		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
//				getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		//---
        currentLocation = null;
        Arrays.fill(passengerCount, 0); //adult, child, senior, disabled, student
        totalFare = 0;
        xStageFare = 0;
		stageCount = db.getStageCountOfRoute(WorkingSession.getInstance().journalRoute.ISN);
		//--
		passengerTypeList = db.getPassengerType();
		if (passengerTypeList == null || passengerTypeList.size() == 0)
		{
			Log.d(TAG, "Could not get Passenger Type discount");
			WorkingSession.getInstance().ShowToast(this,
					"Could not get Passenger Type's discount",
					Toast.LENGTH_LONG);
			finish();
			return;
		}
        //--
        totalFareTextView = (TextView) findViewById(R.id.tvFare);
		passengerTypeGroup = (RadioGroup)findViewById(R.id.checkin_passenger_type_group);
        //--
        progress = new ProgressDialog(this);
        progress.setMessage("Waiting...");
        progress.setCancelable(false);
        //--
        HandlerThread uiThread = new HandlerThread("UIThreadHandler");//to prepare a looper
        uiThread.start();
        uiThreadHandler = new UIThreadHandler(uiThread.getLooper()); //to process UI such as AlertDialog,...
    }

    /*private int getCheckInType()
    {
        Intent input = getIntent();
        int x = input.getIntExtra("CHECK-IN_TYPE", Declarations.CHECK_IN_TYPE_NO_CARD);
        return x;
    }*/

    private void fillMemberInfo()
    {
        TextView x = (TextView) findViewById(R.id.tvCustID);
        x.setText(WorkingSession.getInstance().currentPassenger.UserName + " ("
                + WorkingSession.getInstance().currentPassenger.getFullName() + ")");

        totalFareTextView.setText(String.valueOf(WorkingSession.getInstance().RoundMoney(totalFare)));

    }

    private void ChangeTitle()
    {
        TextView title = (TextView) findViewById(R.id.title_text);
        title.setText(getString(R.string.title_activity_check_in_no_card));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate...");
        // --
        setContentView(R.layout.check_in_v2_cash_4more);
        WorkingSession.getInstance().currentActivity = CheckInV2Cash_4more.this;
        //--
        db = new BusinessDBHandler(CheckInV2Cash_4more.this);
        gpsDb = new GpsDBHandler(CheckInV2Cash_4more.this);
        // --
        super.doCommon();
		ChangeTitle();
		//--
        Initialize();
        //--
        //this.oneStageFare = db.getStageFare(WorkingSession.getInstance().setupJournal.RouteISN, 1);
        //--
        RegisterPayByEvent();
		RegisterPassengerClickEvent();
        RegisterStageClickEvent();
        //--
		passengerTypeGroup.check(R.id.check_in_radio_adult);
        //--
        List<StagesOfRouteValue> stageList = db.getStagesOfRoute(WorkingSession.getInstance().journalRoute.ISN);
        ArrayAdapter<StagesOfRouteValue> stages = new ArrayAdapter<StagesOfRouteValue>(this,
                android.R.layout.simple_dropdown_item_1line, stageList);
        //---
        Spinner xx = (Spinner) findViewById(R.id.checkin_current_location);
        xx.setAdapter(stages);
        xx.setOnItemSelectedListener(currentLocationItemClick);
        //---
        Button xxClick = (Button) findViewById(R.id.checkin_current_location_click);
        xxClick.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Spinner xx = (Spinner) findViewById(R.id.checkin_current_location);
                xx.performClick();
            }
        });

        //---
        fillMemberInfo();

        //---
        if (xStageFare < 0)
        {
            WorkingSession.getInstance().ShowToast(this, "Could not get Fare", Toast.LENGTH_LONG);
        }
        //--
        Log.d(TAG,"Detect current location...");
        //--
        GpsCurrentLocationValue currentGpsLocation = gpsDb.getCurrentLocation(
                WorkingSession.getInstance().setupJournal.ISN);
        if (currentGpsLocation != null)
        {
            Log.d(TAG, String.format("Current location: %d", currentGpsLocation.ClosestStage));
            int idx = -1;
            for (int i = 0; i < stageList.size(); i++)
            {
                Log.d(TAG, String.format("Stage: %d", stageList.get(i).StageISN));
                if (stageList.get(i).StageISN == currentGpsLocation.ClosestStage &&
                        stageList.get(i).BusStationISN == currentGpsLocation.ClosestBusStation)
                {
                    idx = i;
                    break;
                }
            }
            if (idx != -1)
                xx.setSelection(idx);
        }
        //-- play bula voice
        //Utilities.PlayMedia(CheckIn.this, "bula.mp3");
        //---
        //CheckBalanceAndAutoSubmit();
    }

    private AdapterView.OnItemSelectedListener currentLocationItemClick = new AdapterView.OnItemSelectedListener()
    {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long rowId)
        {
            StagesOfRouteValue sel = (StagesOfRouteValue) parent.getItemAtPosition(position);

            Log.d(TAG, String.format("Select location: %d - %s", sel.StageISN, sel.StationName));
            currentLocation = sel;
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView)
        {
            currentLocation = null;
        }
    };

    private void RegisterPayByEvent()
    {
        Button btn = (Button) findViewById(R.id.check_in_v2_refund);
        btn.setOnClickListener(onRefundClick);
		//--
		btn = (Button) findViewById(R.id.check_in_v2_submit);
		btn.setOnClickListener(onSubmitClick);
        //--
		btn = (Button) findViewById(R.id.check_in_v2_cancel);
		btn.setOnClickListener(onCancelClick);

    }

    private MediaPlayer errorVoice;

    private UIThreadHandler uiThreadHandler;

    @Override
    protected void onStart()
    {
        super.onStart();
        Log.d(TAG, "onStart...");

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK)
        {
            if (requestCode == Declarations.REQUEST_CASH_TOP_UP)
            {
                double cashTopUpAmount = data.getDoubleExtra("CASH_TOPUP_AMOUNT", 0);
                if (cashTopUpAmount > 0)
                {
                    //doPayCashAndTopUp(cashTopUpAmount);
                    DoCheckInAsync xTask = new DoCheckInAsync(
                            CheckInV2Cash_4more.this,
                            progress,
                            DoCheckInAsync.CHECK_IN_BY_CASH_TOP_UP
                    );
                    xTask.execute(cashTopUpAmount);
                }
            }
            else if (requestCode == Declarations.REQUEST_STUDENT_VOUCHER)
            {
                double discountAmount = data.getDoubleExtra("VOUCHER_DISCOUNT_AMOUNT", 0);
                String voucherType = data.getStringExtra("VOUCHER_TYPE");
                int collectBalanceType = data.getIntExtra("VOUCHER_COLLECT_BALANCE_TYPE",
                        StudentVoucher.COMPLETE_PAYMENT_BY_VOUCHER);
                double collectAmount = data.getDoubleExtra("VOUCHER_COLLECT_CASH", 0);
                //--
                /*doPayByStudentVoucher(
                        voucherType,
                        discountAmount,
                        collectBalanceType,
                        collectAmount);*/
                DoCheckInAsync xTask = new DoCheckInAsync(
                        CheckInV2Cash_4more.this,
                        progress,
                        DoCheckInAsync.CHECK_IN_BY_STUDENT_VOUCHER
                );
                xTask.execute(
                        voucherType,
                        discountAmount,
                        collectBalanceType,
                        collectAmount
                );
            }
            else if (requestCode == Declarations.REQUEST_REQUIRED_TOP_UP)
            {
                double topUpAmount = data.getDoubleExtra("TOP_UP_AMOUNT_RESULT", 0);
                if (topUpAmount > 0)
                {
                    if (AddTopUpTransaction(topUpAmount))
                    {
                        WorkingSession.getInstance().ShowToast(
                                CheckInV2Cash_4more.this,
                                "Add Top Up transaction successful",
                                Toast.LENGTH_SHORT
                        );

                        //doTapIn();
                        DoCheckInAsync xTask = new DoCheckInAsync(
                                CheckInV2Cash_4more.this,
                                progress,
                                DoCheckInAsync.CHECK_IN_BY_TAP_IN
                        );
                        xTask.execute();
                    }
                }
            }
        }
    }

    private boolean AddTopUpTransaction(double amount)
    {
        //--create top up transaction
        TransactionValue trans = WorkingSession.getInstance().CreateTransaction(
                CheckInV2Cash_4more.this,
                "TOP-UP",
                "Cash",
                0,
                0, 0,
                amount,
                null, //voucher
                null, null,
                0,
                0, 0, 0, 0, 0, 0,
                null,
                ";;;;;");
        if (trans == null)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2Cash_4more.this,
                    "Create Transaction Error",
                    "System Error.\nCould not create transaction, please contact your administrator."
            );

            return false;
        }
        try
        {
            long rx = db.addTransaction(trans);
            trans.ISN = (int) rx;
        }
        catch (Exception ex)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2Cash_4more.this,
                    "Create Transaction Error",
                    "System Error.\nCould not create transaction, please contact your administrator."
            );

            return false;
        }
        //--update passenger balance
        WorkingSession.getInstance().currentPassenger.CurrentBalance += trans.TopUpAmount;
        int x = db.updateMemberBalance(
                WorkingSession.getInstance().currentPassenger.ISN,
                WorkingSession.getInstance().currentPassenger.CurrentBalance);

        return true;
    }

    private int InputValidate()
    {
        int inputValidateResult = 1;

        if (currentLocation == null)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2Cash_4more.this,
                    "Error",
                    "Please select current location");

            inputValidateResult = 0;
        }
        else if (getPassengerCount() <= 0)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2Cash_4more.this,
                    "Error",
                    "Please choose passenger type \n(Adult, Senior, Child or Disabled)"
            );

            inputValidateResult = 0;
        }
		else if (selectedStage <= 0)
		{
			WorkingSession.getInstance().ShowErrorDialog(
					CheckInV2Cash_4more.this,
					"Error",
					"Please choose stage"
			);

			inputValidateResult = 0;
		}

        return inputValidateResult;
    }

    private TransactionValue CreateTransaction(String type, double topUpAmount, VoucherValue vv, boolean updateBalance)
    {
        TransactionValue trans = null;
        try
        {
            //---
            int adultCount = passengerCount[0];
            int seniorCount = passengerCount[2];
            int childCount = passengerCount[1];
            int disabledCount = passengerCount[3];
            //int exemptCount = NoOfPassenger(exempt);
            int studentCount = passengerCount[4];

            String description = String.format("Check-in near %s",
                    currentLocation.StationName);
            description += String.format(" for %d stages. ", selectedStage);

            if (adultCount > 0)
                description += String.format("Adult: %d,", adultCount);
            if (seniorCount > 0)
                description += String.format(" Senior: %d,", seniorCount);
            if (childCount > 0)
                description += String.format(" Child: %d,", childCount);
            if (disabledCount > 0)
                description += String.format(" Disabled: %d,", disabledCount);
            /*if (exemptCount > 0)
                description += String.format(" Exempt: %d,", exemptCount);*/
            if (studentCount > 0)
                description += String.format(" Student: %d,", studentCount);

            description = description.substring(0, description.length() - 1);

            trans = WorkingSession.getInstance().CreateTransaction(
                    CheckInV2Cash_4more.this,
                    "CHECK-IN",
                    type,
                    totalFare,
                    0, //freight
                    0,//ExcessiveBag
                    topUpAmount,
                    vv,
                    currentLocation,
                    null,
                    xStageFare,
                    adultCount,
                    seniorCount,
                    childCount,
                    disabledCount,
                    0,
                    studentCount,
                    null,
                    description
            );
            //--
            if (trans == null)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [1]"
                );
                uiThreadHandler.sendMessage(error);

                /*WorkingSession.getInstance().ShowErrorDialog(
                        CheckIn.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );*/
                return null;
            }

            trans.CheckOutDate = new Date();

            try
            {
                long rx = db.addTransaction(trans);
                trans.ISN = (int) rx;
            }
            catch (Exception ex)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [2]"
                );
                uiThreadHandler.sendMessage(error);

                return null;
            }

            if (trans.ISN == 0)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [3]"
                );
                uiThreadHandler.sendMessage(error);

                return null;
            }
            //WorkingSession.getInstance().ShowToast(CheckIn.this, "Add transaction successful", Toast.LENGTH_SHORT);
            Message msg = uiThreadHandler.CreateShowToastMsg("Add transaction successful");
            uiThreadHandler.sendMessage(msg);
            //--
            if (updateBalance)
            {
                WorkingSession.getInstance().currentPassenger.CurrentBalance += trans.TopUpAmount - trans.FareAmount;
                int x = db.updateMemberBalance(
                        WorkingSession.getInstance().currentPassenger.ISN,
                        WorkingSession.getInstance().currentPassenger.CurrentBalance);
                if (x > 0)
                {
                    msg = uiThreadHandler.CreateShowToastMsg("Update customer balance successful");
                    uiThreadHandler.sendMessage(msg);
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Update customer balance successful", Toast.LENGTH_SHORT);*/
                }
                else
                {
                    msg = uiThreadHandler.CreateShowToastMsg("Update customer balance failed");
                    uiThreadHandler.sendMessage(msg);
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Update customer balance failed", Toast.LENGTH_SHORT);*/
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return trans;
    }

    private int getPassengerCount()
    {
        int x = 0;
        for(int i=0; i<passengerCount.length;i++)
            x+= passengerCount[i];
        return x;
    }

    private String CreateReceiptContent(TransactionValue xx)
    {
        Date date = new Date();
        String receiptDate = Utilities.DateToString(date, "dd/MM/yyyy");
        String receiptTime = Utilities.DateToString(date, "hh:mm a");

        String content = Utilities.StringAlignCenter(48, "BulaMy(Fiji) - BMF etikite  ") //+ "\n"
                + Utilities.StringAlignCenter(48, "BMF Make It Your Choice")
                + Utilities.StringAlignCenter(48, "www.bulamyfiji.com")
                + "\n\n"
				+ Utilities.StringAlignLeftRight(48,
                    "Entry: " + currentLocation.StationName,
                    "Bus Reg.: " + WorkingSession.getInstance().journalBus.BusNumber
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Stages: " + selectedStage,
                    "Driver: " + WorkingSession.getInstance().journalDriver.FullName
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "No. PAX: " + String.valueOf(getPassengerCount()),
                    "Company: DeeCees Fiji Ltd"
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Fare: " +  WorkingSession.getInstance().decimalFormat.format(xStageFare),
                    "TIN: 12683467161"
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Total: " +  String.valueOf(WorkingSession.getInstance().RoundMoney(totalFare)),
                    "Issued: " + receiptDate
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "ACCT Name: ",
                    receiptTime
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "ACCT #: ",
                    "Mode: " + xx.Type
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Balance: ",
                    "Transaction ID: " +  xx.TransactionID
                ) + "\n"
                + "\nPlease Keep Receipt For Your Records\n\n";

        return content;
    }

    private boolean PrintReceipt(TransactionValue xx)
    {
		/*String x = db.getRuntimeValues("print-receipt");
		if(x == null || x.length() == 0)
			x = "1";
		if(x.equals("0"))
			return false;*/
		if(!WorkingSession.getInstance().printReceipt)
			return false;
		//--
        String receipt = CreateReceiptContent(xx);

        int rs = WorkingSession.getInstance().PreparePrintReceiptWifi(CheckInV2Cash_4more.this, receipt, printReceiptCallback);

        if (rs == Declarations.NO_WIFI_PRINTER_SETUP)
        {
            Message error = uiThreadHandler.CreateShowToastMsg(
                    "No printer selected. Please setup one.");
            uiThreadHandler.sendMessage(error);
        }
        else if (rs == Declarations.PRINT_RECEIPT_ERROR)
        {
            Message error = uiThreadHandler.CreateShowToastMsg(
                    "Print receipt failed.");
            uiThreadHandler.sendMessage(error);
        }
        return rs == Declarations.PRINT_RECEIPT_WAITING;
    }

    private final Handler printReceiptCallback = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
			processing = false;
			//--
            Message error = null;
            switch (msg.what)
            {
				case Declarations.WIFI_PRINTER_CONNECTED:
					WorkingSession.getInstance().ShowToast(CheckInV2Cash_4more.this,
							"Printer connected", Toast.LENGTH_SHORT);
					WorkingSession.getInstance().PrintReceipt();
					break;
                case Declarations.WIFI_PRINTER_CONNECTED_ERR:
                    Log.d(TAG, String.format(
                            "WIFI_PRINTER_CONNECTED_ERR. Unable connect to printer %s",
                            WorkingSession.getInstance().wifiPrinterAddress)
                    );
                    progress.dismiss();
                    //--
                    AlertDialog.Builder dialog = new AlertDialog.Builder(CheckInV2Cash_4more.this);
                    dialog.setNegativeButton("OK", new DialogInterface.OnClickListener()
                    {
                        @Override
                        public void onClick(DialogInterface dialog, int which)
                        {
                            uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                        }
                    });
                    AlertDialog alert = dialog.create();
                    alert.setTitle("Print Receipt Error");
                    alert.setMessage(
                            String.format("Unable connect to printer %s",
                                    WorkingSession.getInstance().wifiPrinterAddress)
                    );
                    //--
                    alert.show();
                    //--
                    break;
                case Declarations.WIFI_PRINTER_SEND_FAILED:
                    error = uiThreadHandler.CreateShowToastMsg(
                            "Unable send data to printer.");
                    uiThreadHandler.sendMessage(error);

                    break;
                case Declarations.PRINT_RECEIPT_SUCCESSFUL:
                    error = uiThreadHandler.CreateShowToastMsg(
                            "Print receipt successful.");
                    uiThreadHandler.sendMessage(error);

                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                    break;
            }
        }
    };

    private void doPayByCash()
    {
        try
        {
			Log.e(TAG, "[doPayByCash] Set main INPUT_DIRECT_CHECK_IN = 1");
			Intent next = new Intent(CheckInV2Cash_4more.this, Main.class);
			next.putExtra("INPUT_DIRECT_CHECK_IN", 1);
			if(Main.getInstance() != null)
				Main.getInstance().setIntent(next);
			//--
			Log.e(TAG, "[doPayByCash] Create transaction...");
            TransactionValue trans = CreateTransaction("Cash", 0, null, false);
			//-------------------TEST-------------------
			WorkingSession.getInstance().transactionCount++;
			//-------------------TEST-------------------
			Log.e(TAG, "[doPayByCash] Print receipt...");
            // print receipt
            if (!PrintReceipt(trans))
            {
                uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                //onBackPressed();
            }
        }
        catch (Exception ex)
        {
            Log.e(TAG, "doPayByCash: " + ex.getMessage());
			Message error = uiThreadHandler.CreateShowAlertDialogMsg(
					"System Error",
					"Ticket Error, Please Re-Enter Sale"
					//ex.getMessage()
			);
            uiThreadHandler.sendMessage(error);
        }
		WorkingSession.getInstance().lastCashTransaction = new Date();
		Log.e(TAG, "[doPayByCash] Done");
    }

    private void doPayByStudentVoucher(
            String voucherType, double discountAmount,
            int collectBalanceType, double collectAmount)
    {
        try
        {
			Log.e(TAG, "[doPayByStudentVoucher] Set main INPUT_DIRECT_CHECK_IN = 1");
			Intent next = new Intent(CheckInV2Cash_4more.this, Main.class);
			next.putExtra("INPUT_DIRECT_CHECK_IN", 1);
			if(Main.getInstance() != null)
				Main.getInstance().setIntent(next);
			//--
			Log.e(TAG, "[doPayByStudentVoucher] Create transaction...");
            VoucherValue vv = new VoucherValue();
            vv.VoucherType = voucherType;
            vv.VoucherAmount = discountAmount;

            TransactionValue trans = null;
            if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_VOUCHER)
            {
                trans = CreateTransaction(
                        "Student-Voucher",
                        0,
                        vv,
                        false);
            }
            else if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_BMF)
            {
                trans = CreateTransaction(
                        "BMF",
                        0,
                        vv,
                        false);
            }
            else if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_CASH)
            {
                trans = CreateTransaction(
                        "Cash",
                        collectAmount,
                        vv,
                        false);
            }
            if (trans == null)
            {
                WorkingSession.getInstance().ShowErrorDialog(
                        CheckInV2Cash_4more.this,
                        "Error",
                        "System Error.\nCould not add Transaction"
                );
				processing = false;
                return;
            }
			//-------------------TEST-------------------
			WorkingSession.getInstance().transactionCount++;
			//-------------------TEST-------------------
            // print receipt
			Log.e(TAG, "[doPayByStudentVoucher] Print receipt...");
            if (!PrintReceipt(trans))
            {
                uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                //onBackPressed();
            }
        }
        catch (Exception ex)
        {
            Log.e(TAG, "doPayByStudentVoucher: " + ex.getMessage());
			Message error = uiThreadHandler.CreateShowAlertDialogMsg(
					"System Error",
					"Ticket Error, Please Re-Enter Sale"
            );
            uiThreadHandler.sendMessage(error);

            /*WorkingSession.getInstance().ShowToast(CheckIn.this, ex.getMessage(),
                    Toast.LENGTH_LONG);*/
        }
		WorkingSession.getInstance().lastCashTransaction = new Date();
		Log.e(TAG, "[doPayByStudentVoucher] Done");
    }

    OnClickListener onCancelClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
			Log.d(TAG, "Canceling...");
			hardKeyBack = true;

			onBackPressed();
        }
    };

    private boolean processing = false;
	private boolean hardKeyBack = true;

    @Override
    public void onBackPressed()
    {
		try
		{
			progress.dismiss();
		}
		catch (Exception ex)
		{
			Log.e(TAG, "[onBackPress] " + ex.toString());
		}
		//--
		Intent next = new Intent(CheckInV2Cash_4more.this, Main.class);
		if(hardKeyBack)
		{
			Log.d(TAG, "[onBackPress] Hard key");

			next.putExtra("INPUT_DIRECT_CHECK_IN", 0);
			if(Main.getInstance() != null)
				Main.getInstance().setIntent(next);
		}
		else
		{
			//--
			String cardNumber = db.getRuntimeValues("defaultCard");
			if (cardNumber == null || cardNumber.length() == 0)
			{
				Log.d(TAG, "[onBackPress] 1");
				next.putExtra("INPUT_DIRECT_CHECK_IN", 0);
				if(Main.getInstance() != null)
					Main.getInstance().setIntent(next);
			}
			else
			{
				Log.d(TAG, "[onBackPress] 2");
				//--
				next.putExtra("INPUT_DIRECT_CHECK_IN", 1);
				if(Main.getInstance() != null)
					Main.getInstance().setIntent(next);
			}
		}
		//super.onBackPressed();
		//--
        //next.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        //startActivity(next);
        finish();
    }

//    @Override
//    public void onNewIntent(Intent intent)
//    {
//        String action = intent.getAction();
//        Log.d(TAG, String.format("[onNewIntent] Action: %s", action));
//
//        if (action != null &&
//			(action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)
//                || action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
//            && !processing)
//        {
//            String[] result = Utilities.readNFCTagContentAndSerial(CheckInV2Cash_4more.this, intent);
//            //--result[0] = TagSerial, result[1] = Tag content
//            if (result == null || result.length < 2)
//                return;
//
//            if (result[1].length() == 0)
//            {
//				WorkingSession.getInstance().ShowErrorDialog(
//						CheckInV2Cash_4more.this,
//						"Error",
//                        "Invalid NFC Tag Content"
//                );
//				return;
//            }
//
//            MemberValue member = db.getMemberByCard(result[1], result[0]);
//
//            if (member != null)
//            {
//				// go back to Home
//				Intent mainScreen = new Intent(CheckInV2Cash_4more.this, Main.class);
//				mainScreen.putExtra("INPUT_CUSTOMER", member.CardNumber);
//				//startActivity(mainScreen);
//
//				if(Main.getInstance() != null)
//					Main.getInstance().setIntent(mainScreen);
//				finish();
//            }
//            else
//            {
//                //Utilities.PlayMedia(CheckIn.this, "C.mp3");
//                WorkingSession.getInstance().ShowErrorDialog(
//						CheckInV2Cash_4more.this,
//                        "Error",
//                        "Invalid Card Number: " + result[1]
//                );
//            }
//        }
//        else
//        {
//            Log.d(TAG, "Action: " + action + ", on processing current task");
//        }
//    }

    @Override
    protected void onResume()
    {
        Log.d(TAG, "[onResume] ....");
        super.onResume();
//        if (nfcAdapter != null)
//        {
//            nfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
//            // mAdapter.enableForegroundNdefPush(this);
//        }
    }

    @Override
    protected void onPause()
    {
        Log.d(TAG, "[onPause] ....");
        super.onPause();
//        if (nfcAdapter != null)
//        {
//            nfcAdapter.disableForegroundDispatch(this);
//            //nfcAdapter.disableForegroundNdefPush(this);
//            nfcAdapter.setNdefPushMessage(null, this);
//        }

        if(errorVoice != null)
            errorVoice.stop();
        //WorkingSession.getInstance().CancelShowingToast();
    }

    @Override
    protected void onDestroy()
    {
        Log.d(TAG, "[onDestroy] ....");
        super.onDestroy();
        /*if (autoSubmit != null)
            autoSubmit.cancel();*/
        if(errorVoice != null)
            errorVoice.stop();

    }

    private final class UIThreadHandler extends Handler
    {
        private final String TAG = "CheckInUIThreadHandler";
        public static final int MSG_COUNT_DOWN = 0x10;
        public static final int SHOW_TOAST = 0x11;
        public static final int SHOW_ALERT_DIALOG = 0x12;
        public static final int DO_CHECK_IN_BY_CASH = 0x13;
        public static final int DO_BACK_PRESS = 0x14;
        private int currentCountDownValue = Declarations.TAP_IN_TIMEOUT_SECONDS;


        public UIThreadHandler(Looper lp)
        {
            super(lp);
        }

        @Override
        public void handleMessage(Message msg)
        {
            try
            {
                switch (msg.what)
                {
                    case UIThreadHandler.SHOW_TOAST:
                    {
                        String content = msg.getData().getString("TOAST_CONTENT", "");
                        if(content.length() == 0)
                            break;
                        WorkingSession.getInstance().ShowToast(
                                CheckInV2Cash_4more.this,
                                content,
                                Toast.LENGTH_SHORT);
                        break;
                    }
                    case UIThreadHandler.SHOW_ALERT_DIALOG:
                    {
                        String title = msg.getData().getString("DIALOG_TITLE", "");
                        String content = msg.getData().getString("DIALOG_CONTENT", "");
                        if(content.length() == 0)
                            break;
                        WorkingSession.getInstance().ShowErrorDialog(
                                CheckInV2Cash_4more.this,
                                title,
                                content);
                        break;
                    }
                    case DO_CHECK_IN_BY_CASH:
                    {
                        //Thread.sleep(500);
                        Log.d(TAG, "Do Check-in by cash");
                        //--
                        DoCheckInAsync xTask = new DoCheckInAsync(
                                CheckInV2Cash_4more.this,
                                progress,
                                DoCheckInAsync.CHECK_IN_BY_CASH
                        );
                        xTask.execute();
                        //--
                        break;
                    }
                    case DO_BACK_PRESS:
						Thread.sleep(300);
						hardKeyBack = false;
						runOnUiThread(new Runnable()
						{
							@Override
							public void run()
							{
								onBackPressed();
							}
						});
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, String.format("[MSG:%d] %s", msg.what, ex.getMessage()));
            }
        }

        public Message CreateShowToastMsg(String content)
        {
            Message msg = new Message();
            msg.what = SHOW_TOAST;

            Bundle data = new Bundle();
            data.putString("TOAST_CONTENT", content);
            msg.setData(data);

            return msg;
        }

        public Message CreateShowAlertDialogMsg(String dialogTitle, String content)
        {
            Message msg = new Message();
            msg.what = SHOW_ALERT_DIALOG;

            Bundle data = new Bundle();
            data.putString("DIALOG_TITLE", dialogTitle);
            data.putString("DIALOG_CONTENT", content);
            msg.setData(data);

            return msg;
        }
    }


    public class DoCheckInAsync extends AsyncTask<Object, Void, Void>
    {
        public static final int CHECK_IN_BY_BMF = 1000;
        public static final int CHECK_IN_BY_CASH = 1001;
        public static final int CHECK_IN_BY_CASH_TOP_UP = 1002;
        public static final int CHECK_IN_BY_STUDENT_VOUCHER = 1003;
        public static final int CHECK_IN_BY_TAP_IN = 1004;

        private ProgressDialog progress;
        private Context callerContext;
        private int checkInType;

        public DoCheckInAsync(Context context, ProgressDialog dialog, int checkInType)
        {
            callerContext = context;
            progress = dialog;
            this.checkInType = checkInType;
        }

        public void onPreExecute()
        {
            processing = true;
            progress.show();
            //--
            super.onPreExecute();
        }

        public Void doInBackground(Object... inputValues)
        {
            try
            {
                switch (this.checkInType)
                {
                    case CHECK_IN_BY_CASH:
						//Thread.sleep(500);
                        doPayByCash();
                        break;
                    case CHECK_IN_BY_STUDENT_VOUCHER:
                        doPayByStudentVoucher(
                                String.valueOf(inputValues[0]), //voucherType
                                ((Number)inputValues[1]).doubleValue(), //discountAmount
                                ((Number)inputValues[2]).intValue(), //collectBalanceType
                                ((Number)inputValues[3]).doubleValue() //collectAmount
                        );
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, "[DoCheckInAsync] " + ex.getMessage());
            }

            return null;
        }

        public void onPostExecute(Void unused)
        {
            processing = false;
            super.onPostExecute(unused);
        }
    }

    /*private OnClickListener onAdultStageClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button button = (Button)v;
            Log.d(TAG, "[onAdultStageClick] " + button.getText());
            //--
            Arrays.fill(passengerCount, 0);
            passengerCount[0] = 1;
            selectedStage =  Integer.parseInt(button.getText().toString());
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
            totalFare = passengerCount[0] * xStageFare * (1 - GetPassengerTypeDiscount("adult"));
            //--
            CompletePaymentByCash();
        }
    };*/

    /*private OnClickListener onChildStageClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button button = (Button)v;
            Log.d(TAG, "[onChildStageClick] " + button.getText());
            //--
            Arrays.fill(passengerCount, 0);
            passengerCount[1] = 1;
            selectedStage =  Integer.parseInt(button.getText().toString());
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
            totalFare = passengerCount[1] * xStageFare * (1 - GetPassengerTypeDiscount("child"));
            //--
            CompletePaymentByCash();
        }
    };*/

    /*private OnClickListener onSeniorStageClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button button = (Button)v;
            Log.d(TAG, "[onSeniorStageClick] " + button.getText());
            //--
            Arrays.fill(passengerCount, 0);
            passengerCount[2] = 1;
            selectedStage =  Integer.parseInt(button.getText().toString());
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
            totalFare = passengerCount[2] * xStageFare * (1 - GetPassengerTypeDiscount("senior"));
            //--
            CompletePaymentByCash();
        }
    };*/

    /*private OnClickListener onDisabledStageClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button button = (Button)v;
            Log.d(TAG, "[onDisabledStageClick] " + button.getText());
            //--
            Arrays.fill(passengerCount, 0);
            passengerCount[3] = 1;
            selectedStage =  Integer.parseInt(button.getText().toString());
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
            totalFare = passengerCount[3] * xStageFare * (1 - GetPassengerTypeDiscount("disabled"));
            //--
            CompletePaymentByCash();
        }
    };*/

    /*private void RegisterPassengerStageClickEvent()
    {
        for(int i=1; i<= selectedStage && i <4; i++)
        {
            int id = -1;

            id = Utilities.getResId("stage_adult_" + i, CheckInV2Cash_4more.this, R.id.class);
            if(id > -1)
                ((Button) findViewById(id)).setOnClickListener(onAdultStageClick);
            //--
            id = Utilities.getResId("stage_child_" + i, CheckInV2Cash_4more.this, R.id.class);
            if(id > -1)
                ((Button) findViewById(id)).setOnClickListener(onChildStageClick);
            //--
            id = Utilities.getResId("stage_senior_" + i, CheckInV2Cash_4more.this, R.id.class);
            if(id > -1)
                ((Button) findViewById(id)).setOnClickListener(onSeniorStageClick);
            //--
            id = Utilities.getResId("stage_disabled_" + i, CheckInV2Cash_4more.this, R.id.class);
            if(id > -1)
                ((Button) findViewById(id)).setOnClickListener(onDisabledStageClick);
            //--
            id = Utilities.getResId("stage_student_" + i, CheckInV2Cash_4more.this, R.id.class);
            if(id > -1)
            {
                Button btn = (Button)findViewById(id);
                btn.setTag(i);
                btn.setOnClickListener(onStudentClick);
            }
        }
        *//*Button btn = (Button)findViewById(R.id.stage_student_1);
        btn.setTag(1);
        btn.setOnClickListener(onStudentClick);
        //--
        btn = (Button)findViewById(R.id.stage_student_2);
        btn.setTag(2);
        btn.setOnClickListener(onStudentClick);
        //--
        btn = (Button)findViewById(R.id.stage_student_3);
        btn.setTag(3);
        btn.setOnClickListener(onStudentClick);*//*
    }*/

	private int getDIPFromPixel(int value)
	{
		int x = (int) TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP,
				value,
				getResources().getDisplayMetrics());
		return x;
	}

	private void RegisterStageClickEvent()
	{
		LinearLayout container = (LinearLayout)findViewById(R.id.checkin_v2_stage_container);

		int stagesPerRow = 3;
		int rowCount = stageCount / stagesPerRow + (stageCount % stagesPerRow > 1? 1: 0);

		Resources res = this.getResources();
		for(int r=0;r<rowCount;r++)
		{
			LinearLayout layout = new LinearLayout(this);
			LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.WRAP_CONTENT,  //width
					LinearLayout.LayoutParams.WRAP_CONTENT); //height
			layout.setOrientation(LinearLayout.HORIZONTAL);
			param.setMargins(30,5,0,0);
			layout.setLayoutParams(param);
			//--
			int rowColorId = Utilities.getResId(
					"stage_button_color" + ((r+1)>7?7:(r+1)) + "_states",
					CheckInV2Cash_4more.this,
					R.drawable.class
			);
			//--
			int c = 0;
			for(c=0; c<stagesPerRow && r*stagesPerRow+c < stageCount; c++)
			{
				Button stage = new Button(CheckInV2Cash_4more.this);
				param = new LinearLayout.LayoutParams(
						getDIPFromPixel(130),//LinearLayout.LayoutParams.WRAP_CONTENT,  //width
						getDIPFromPixel(90));//LinearLayout.LayoutParams.WRAP_CONTENT); //height
				param.setMargins(40, 0, (c == stagesPerRow-1)? 10: 0, 10);
				//--
				stage.setLayoutParams(param);
				stage.setText(String.valueOf(r*stagesPerRow+c+1));
				stage.setTextColor(Color.BLACK);
				stage.setTextSize(TypedValue.COMPLEX_UNIT_SP, 36);
				stage.setBackground(res.getDrawable(rowColorId));
				stage.setOnClickListener(onStageButtonClick);
				stage.setTag("stage" + String.valueOf(r*stagesPerRow+c+1));
				//--
				layout.addView(stage);
			}
			//--
			container.addView(layout);
		}//end of for
	}

    private OnClickListener onRefundClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Intent input = new Intent(CheckInV2Cash_4more.this, refund.class);
            input.putExtra("OPTION_NO_CARD", 1);
            startActivity(input);
        }
    };

	private OnClickListener onSubmitClick = new OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
			CompletePaymentByCash();
		}
	};

    private void CompletePaymentByCash()
    {
        if (InputValidate() != 1) //not validate or waiting for confirm
            return;

        //show total fare
        totalFareTextView.setText(String.valueOf(WorkingSession.getInstance().RoundMoney(totalFare)));
        //--
        DoCheckInAsync xTask = new DoCheckInAsync(
                CheckInV2Cash_4more.this,
                progress,
                DoCheckInAsync.CHECK_IN_BY_CASH
        );
        xTask.execute();
    }

    /*private OnClickListener onStudentClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button btn = (Button)v;
            int x = Integer.parseInt(btn.getTag().toString());
            //--
            Log.d(TAG, "[onStudentClick] " + x);
            //--
            double discountAmount = (x == 1? 0.75d : (x == 2? 0.55d: 0.35d));
            String voucherType = (x == 1? "Red" : (x == 2? "Blue" : "Yellow"));
            int collectBalanceType = StudentVoucher.COMPLETE_PAYMENT_BY_VOUCHER;
            double collectAmount = 0;
            //--
            Arrays.fill(passengerCount, 0);
            passengerCount[4] = 1;
            selectedStage =  1;
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
            totalFare = passengerCount[4] * xStageFare * (1 - GetPassengerTypeDiscount("student"));
            //--
            CompletePaymentByVoucher(
                    voucherType,
                    discountAmount,
                    collectBalanceType,
                    collectAmount
            );
        }
    };*/

    /*private void CompletePaymentByVoucher(
            String voucherType,
            double discountAmount,
            int collectBalanceType,
            double collectAmount
    )
    {
        if (InputValidate() != 1) //not validate or waiting for confirm
            return;
        //show total fare
        totalFareTextView.setText(WorkingSession.getInstance().decimalFormat.format(totalFare));
        //--
        DoCheckInAsync xTask = new DoCheckInAsync(
                CheckInV2Cash_4more.this,
                progress,
                DoCheckInAsync.CHECK_IN_BY_STUDENT_VOUCHER
        );
        xTask.execute(
                voucherType,
                discountAmount,
                collectBalanceType,
                collectAmount
        );
    }*/

	private int getPassengerType()
	{
		int x = -1;
		for(int i=0;i<passengerCount.length;i++)
		{
			if(passengerCount[i] > 0)
				x = i;
		}
		return x;
	}

	private OnClickListener onStageButtonClick = new OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
			Button button = (Button)v;
			Log.d(TAG, "[onStageButtonClick] " + button.getText());
			//--
			selectedStage =  Integer.parseInt(button.getText().toString());
			xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, selectedStage);
			int pgrPos = getPassengerType();
			if(pgrPos == 0)
				totalFare = passengerCount[pgrPos] * xStageFare * (1 - GetPassengerTypeDiscount("adult"));
			else if(pgrPos == 1)
				totalFare = passengerCount[pgrPos] * xStageFare * (1 - GetPassengerTypeDiscount("child"));
			else if(pgrPos == 2)
				totalFare = passengerCount[pgrPos] * xStageFare * (1 - GetPassengerTypeDiscount("senior"));
			else if(pgrPos == 3)
				totalFare = passengerCount[pgrPos] * xStageFare * (1 - GetPassengerTypeDiscount("disabled"));
			else
				totalFare = 0;
			//--
			totalFareTextView.setText(String.valueOf(WorkingSession.getInstance().RoundMoney(totalFare)));
			//--
			//clear other RED text
			LinearLayout container = (LinearLayout)findViewById(R.id.checkin_v2_stage_container);
			for(int i = 1; i<= stageCount; i++)
			{
				View stageButton = container.findViewWithTag("stage" + i);
				if(stageButton != null)
					((Button)stageButton).setTextColor(Color.BLACK);
			}
			//set this button to RED
			button.setTextColor(Color.RED);

			//CompletePaymentByCash();
		}
	};

	private void RegisterPassengerClickEvent()
	{
		passengerTypeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
		{
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId)
			{
				RadioButton pgrType = (RadioButton)findViewById(checkedId);
				if(pgrType == null || !pgrType.isChecked())
					return;
				Log.d(TAG, "[passengerTypeGroup] " + pgrType.getText());
				//passengerCount = new int[5]; //adult, child, senior, disabled, student
				int pos = -1;
				if(checkedId == R.id.check_in_radio_adult)
					pos = 0;
				else if(checkedId == R.id.check_in_radio_child)
					pos = 1;
				else if(checkedId == R.id.check_in_radio_senior)
					pos = 2;
				else if(checkedId == R.id.check_in_radio_disable)
					pos = 3;
				if(pos != -1)
				{
					Arrays.fill(passengerCount, 0);
					passengerCount[pos] = 1;
					//--
					if(pos == 0)
						totalFare = passengerCount[pos] * xStageFare * (1 - GetPassengerTypeDiscount("adult"));
					else if(pos == 1)
						totalFare = passengerCount[pos] * xStageFare * (1 - GetPassengerTypeDiscount("child"));
					else if(pos == 2)
						totalFare = passengerCount[pos] * xStageFare * (1 - GetPassengerTypeDiscount("senior"));
					else if(pos == 3)
						totalFare = passengerCount[pos] * xStageFare * (1 - GetPassengerTypeDiscount("disabled"));
					else
						totalFare = 0;
					//--
					totalFareTextView.setText(String.valueOf(WorkingSession.getInstance().RoundMoney(totalFare)));
				}
			}
		});
	}
}
